import _data from "./_data";
import globalConfig from "./config";
import onMessage from "./onSocketMessage";

let websocket = {
    // 是否连接
    isOpen: false,
    // 当前网络状态
    _netWork: true,
    // 是否人为退出
    _isClosed: false,
    // 心跳检测频率
    _timeout: 30000,
    // 当前重连次数
    _connectNum: 0,
    // 心跳检测和断线重连开关，true为启用，false为关闭
    _heartCheck: true,
    _isReconnection: true,
    _timeoutObj: null,
    msgQueue: [],
    // 心跳重置
    _reset() {
        clearTimeout(this._timeoutObj);
        return this;
    },
    // 心跳开始
    _start() {
        let _this = this;
        this._timeoutObj = setInterval(() => {
            //发送心跳
            _this.sendHeartbeatData();
        }, this._timeout);
    },
    sendHeartbeatData() {
        this.send({
            uri: "/chat/heartbeat",
            data: {
                time: (new Date()).getTime()
            }
        })
    },
    // 重连方法，会根据时间频率越来越慢
    reConnect(options) {
        let timer, _this = this;
        let token = _data.data('token');
        if (!token) {
            _this._reset();
            return;
        }
        if (this._connectNum < 20) {
            timer = setTimeout(() => {
                _this.initWebSocket(options)
            }, 2000)
            this._connectNum += 1;
        } else if (this._connectNum < 50) {
            timer = setTimeout(() => {
                _this.initWebSocket(options)
            }, 5000)
            this._connectNum += 1;
        } else {
            timer = setTimeout(() => {
                _this.initWebSocket(options)
            }, 10000)
            this._connectNum += 1;
        }
        console.log('断线重连:' + this._connectNum);
    },
    onSocketOpened() {
        // 打开已登录开关
        this.isOpen = true;
        console.log('socket已打开');
        _data.data('socket_state', 1);
        uni.$emit('socket_state', 1);
        // 发送心跳
        if (this._heartCheck) {
            this._reset()._start();
        }
        // 打开网络开关
        this._netWork = true;
        /** 这里如果有需要发送的数据 */
        if (this.msgQueue.length > 0) {
            console.log('发送队列');
            for (let i in this.msgQueue) {
                this.send(this.msgQueue[i]);
            }
            this.msgQueue = [];
        }
    },
    initWebSocket() {
        let _this = this;
        let token = _data.data('token');
        if (!token || _this.isOpen) {
            return this;
        }
		if(this.isOpen){
			return;
		}
        uni.connectSocket({
            url: globalConfig.socket_url,
            header: {
                'content-type': 'application/json',
                'Sec-WebSocket-Protocol': token
            },
            protocols: [token],
            method: 'GET',
            success(res) {
                console.log('connectSocket');
            },
            fail(err) {
                uni.showModal({
                    content: JSON.stringify(err) + '---socket 接口调用失败',
                });
            }
        });
        uni.onSocketOpen((res) => {
            this.onSocketOpened();
        });
        /** 绑定服务器消息事件 */
        uni.onSocketMessage((res) => {
            res = JSON.parse(res.data);
            if (!(res.cmd in onMessage)) {
                console.log('接受到无效的消息', res)
                return;
            }
            onMessage[res.cmd](res.data);
        });
        uni.onSocketClose((err) => {
            _this.isOpen = false;
            _data.data('socket_state', 0);
            uni.$emit('socket_state', 0);
            console.log('onSocketClose:服务器已断开连接');
            _this._reset();
            _this.reConnect();
        });
        uni.onSocketError((err) => {
            _this.isOpen = false;
            console.log('onSocketError:' + JSON.stringify(err))
            _data.data('socket_state', 0);
            uni.$emit('socket_state', 0);
            uni.showToast({
                title: '连接服务器失败' + JSON.stringify(err),
                icon: 'none',
                duration: 3000
            });
            _this._reset();
            _this.reConnect();
        });
        return this;
    },
    send(send_data) {
        if (!this.isOpen) {
            this.msgQueue.push(send_data)
            this.initWebSocket();
        }else{
            console.log('send '+JSON.stringify(send_data));
            uni.sendSocketMessage({
                data: JSON.stringify(send_data),
                fail(err) {
                    console.log('发送失败' + JSON.stringify(err))
                }
            });
        }
    },

}
export default websocket
